package org.taobao.ibatiside.ui.util;

import java.util.Iterator;
import java.util.List;

import javax.management.RuntimeErrorException;

import org.apache.commons.lang.StringUtils;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.IPackageFragment;
import org.eclipse.jdt.core.IPackageFragmentRoot;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jdt.internal.ui.refactoring.contentassist.ControlContentAssistHelper;
import org.eclipse.jdt.internal.ui.refactoring.contentassist.JavaPackageCompletionProcessor;
import org.eclipse.jface.dialogs.TitleAreaDialog;
import org.eclipse.jface.viewers.ArrayContentProvider;
import org.eclipse.jface.viewers.ComboViewer;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.model.WorkbenchLabelProvider;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;

public abstract class ResourceDialog extends TitleAreaDialog {
	protected Text packageName;
	protected Text resourceName;
	protected ComboViewer srcRootViewer;
	protected Label lblNotes;
	protected final IJavaProject project;
	protected boolean checkExist = true;
	protected String defaultName;
	private JavaPackageCompletionProcessor pkgProcessor;
	private IPath resourcePath;
	/**
	 * Create the dialog.
	 * @param parentShell
	 */
	public ResourceDialog(Shell parentShell, IJavaProject jp) {
		super(parentShell);
		this.project = jp;
	}
	public void setDefaultName(String defaultName) {
		this.defaultName = defaultName;
	}
	public IPath getResourcePath(){
		return resourcePath;
	}
	public void setResourcePath(IPath resourcePath) {
		this.resourcePath = resourcePath;
	}
	public void setCheckExist(boolean checkExist) {
		this.checkExist = checkExist;
	}
	public abstract String getFileExtension();

	/**
	 * Create contents of the dialog.
	 * @param parent
	 */
	@Override
	protected Control createDialogArea(Composite parent) {
		Composite area = (Composite) super.createDialogArea(parent);
		pkgProcessor= new JavaPackageCompletionProcessor();
		Composite container = new Composite(area, SWT.NONE);
		GridLayout gl_container = new GridLayout(3, false);
		gl_container.marginTop = 10;
		gl_container.marginLeft = 10;
		container.setLayout(gl_container);
		container.setLayoutData(new GridData(GridData.FILL_BOTH));
		
		Label label = new Label(container, SWT.RIGHT);
		label.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1));
		label.setText("Source Folder");
		label.setAlignment(SWT.RIGHT);
		label.setBounds(0, 0, 81, 17);
		
		srcRootViewer = new ComboViewer(container, SWT.READ_ONLY);
		Combo srcRoots = srcRootViewer.getCombo();
		srcRoots.setLayoutData(new GridData(SWT.LEFT, SWT.CENTER, true, false, 2, 1));
		srcRoots.setBounds(0, 0, 174, 25);
		
		Label label_1 = new Label(container, SWT.RIGHT);
		label_1.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1));
		label_1.setText("Package");
		label_1.setAlignment(SWT.RIGHT);
		label_1.setBounds(0, 0, 49, 17);
		
		packageName = new Text(container, SWT.BORDER);
		GridData gd_packageName = new GridData(SWT.LEFT, SWT.CENTER, false, false, 1, 1);
		gd_packageName.widthHint = 250;
		packageName.setLayoutData(gd_packageName);
		packageName.setBounds(0, 0, 259, 23);
		
		Button button = new Button(container, SWT.NONE);
		button.addSelectionListener(new SelectionAdapter() {
			@Override
			public void widgetSelected(SelectionEvent e) {
				try {
					IPackageFragment choosed_pkg = WorkspaceUtil.choosePackage2(getParentShell(),(IPackageFragmentRoot) ((StructuredSelection)srcRootViewer.getSelection()).getFirstElement());
					if (choosed_pkg != null) packageName.setText(choosed_pkg.getElementName());
				} catch (JavaModelException e1) {
					e1.printStackTrace();
				}
			}
		});
		button.setText("Browser...");
		button.setBounds(0, 0, 69, 27);
		
		Label label_2 = new Label(container, SWT.RIGHT);
		label_2.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1));
		label_2.setText("Name");
		label_2.setBounds(0, 0, 81, 17);
		
		resourceName = new Text(container, SWT.BORDER);
		GridData gd_resourceName = new GridData(SWT.LEFT, SWT.CENTER, false, false, 1, 1);
		gd_resourceName.widthHint = 200;
		resourceName.setLayoutData(gd_resourceName);
		resourceName.setBounds(0, 0, 191, 23);
		
		lblNotes = new Label(container, SWT.NONE);
		srcRootViewer.setContentProvider(new ArrayContentProvider());
		srcRootViewer.setLabelProvider(new WorkbenchLabelProvider());
		srcRootViewer.setInput(WorkspaceUtil.getSourceRoot(project));
		ControlContentAssistHelper.createTextContentAssistant(packageName, pkgProcessor);
		srcRootViewer.addSelectionChangedListener(new ISelectionChangedListener() {
			@Override
			public void selectionChanged(SelectionChangedEvent event) {
				IPackageFragmentRoot first_root =(IPackageFragmentRoot) ((IStructuredSelection)event.getSelection()).getFirstElement();
				if (first_root!= null){
					pkgProcessor.setPackageFragmentRoot(first_root);
				}
			}
		});
		if (StringUtils.isNotBlank(defaultName))
			resourceName.setText(defaultName);
		restoreViewFromPath();
		return area;
	}
	private void restoreViewFromPath() {
		if (resourcePath != null){
			//first, find root
			List<IPackageFragmentRoot> roots = WorkspaceUtil.getSourceRoot(project);
			IPath current_root = null;
			//match roots
			for (Iterator iterator = roots.iterator(); iterator.hasNext();) {
				IPackageFragmentRoot one_root = (IPackageFragmentRoot) iterator
						.next();
				if ((current_root = one_root.getResource().getFullPath()).isPrefixOf(resourcePath)){
					srcRootViewer.setSelection(new StructuredSelection(one_root));
					break;
				}
			}
			IPath pkg_res = resourcePath.removeFirstSegments(current_root.segmentCount()).removeFileExtension();
			String resource_name = pkg_res.lastSegment();
			resourceName.setText(resource_name);
			String pkg_name = pkg_res.removeLastSegments(1).toString().replace('/', '.');
			packageName.setText(pkg_name);
		}
	}
	protected String validateResource(){
		if (srcRootViewer.getSelection().isEmpty()){
			return "Source Folder must be selected";
		}
		String resource_name = StringUtils.trim(resourceName.getText());
		if (StringUtils.isBlank(resource_name)){
			return "Resoruce's name is required";
		}
		IPackageFragmentRoot srcRoot = (IPackageFragmentRoot)((IStructuredSelection)srcRootViewer.getSelection()).getFirstElement();
		IPackageFragment input_pkg = srcRoot.getPackageFragment(packageName.getText());
		if (!input_pkg.exists()){
			try {
				srcRoot.createPackageFragment(packageName.getText(), true, new NullProgressMonitor());
			} catch (JavaModelException e) {
				e.printStackTrace();
				return "Can't create package because "+e.getLocalizedMessage();
			}
		}
		resourcePath = input_pkg.getResource().getFullPath().append(resource_name).addFileExtension(getFileExtension());
		IResource try_resource ;
		if (checkExist && (try_resource = ResourcesPlugin.getWorkspace().getRoot().findMember(resourcePath))!= null){
			return "resource "+try_resource.getProjectRelativePath().toString()+" exists, please use a different name!";
		}
		return null;
	}
	@Override
	protected void okPressed() {
		String error = validateResource();
		if (error != null){
			setErrorMessage(error);
		}else{
			super.okPressed();
		}
	}

	/**
	 * Return the initial size of the dialog.
	 */
	@Override
	protected Point getInitialSize() {
		return new Point(500, 280);
	}

}
